<?php
/**
 * Created by PhpStorm.
 * User: tandunzhao
 * Date: 2018/5/28
 * Time: 上午10:52
 */

namespace App\Libs\Pay;


use App\Libs\Pay\Merchants\OfficialPay;
use App\Modules\Order\Services\OrderRefundService;
use App\Modules\Order\Services\OrderService;
use App\Modules\Pay\Services\PayMerchantService;
use App\Modules\Pay\Services\PayPaymentService;
use App\Modules\Pay\Services\PayWithdrawCashService;
use App\Modules\User\Models\User;
use App\Modules\User\Services\UserBillService;
use Log;

class WechatPay
{
    private static $_instance;

    public static function instance($merchant, $config=[]) {
        if(!self::$_instance) {
            switch ($merchant) {
                case 'OFFICIALPAY':
                    //微信官方支付
                    self::$_instance = new OfficialPay();
                    self::$_instance->setConfig($config);
                    break;
                default:
                    return null;
            }
        }
        return self::$_instance;
    }


    /**
     * 退款
     * @param int $orderId 退款金额 单位 分
     * @param double $refundMoney 退款金额 单位 分
     * @param string $remark
     * @return array ['result' => false, 'msg' => ""]
     */
    public static function companyPayToPersonRefund($orderId, $refundMoney, $remark = '') {
        $resultData = [
            'result' => false,
            'msg' => "",
        ];
        $order = OrderService::findById($orderId);
        if(!$order) {
            $resultData['result'] = false;
            $resultData['msg'] = "订单不存在";
            return $resultData;
        }
        if($refundMoney > ($order->money)*100) {
            $resultData['result'] = false;
            $resultData['msg'] = "退款金额大于支付金额";
            return $resultData;
        }

        $payMerchant = PayMerchantService::get($order->pay_merchant_id);
        if(!$payMerchant) {
            $resultData['result'] = false;
            $resultData['msg'] = "企业支付通道不存在";
            return $resultData;
        }
        if(!$payMerchant) {
            $resultData['result'] = false;
            $resultData['msg'] = "企业支付通道不存在";
            return $resultData;
        }
        if($payMerchant && !in_array($payMerchant->source, ['OFFICIALPAY'])) {
            $resultData['result'] = false;
            $resultData['msg'] = "暂时不支持其他支付通道退款";
            return $resultData;
        }
        $payConfig = [];
        if($payMerchant->config_info){
            $publicPath = public_path();
            $payConfig = json_decode($payMerchant->config_info,true);
            $payConfig['cert_path'] = $publicPath.'/' .$payConfig['cert_path'];
            $payConfig['key_path'] = $publicPath.'/' .$payConfig['key_path'];
        }

        $saveAmount = $refundMoney / 100;

        $refund_no = date("YmdHis").hexdec(uniqid());
        $orderRefundData = [
            'task_id' => $order->task_id,
            'uid' => $order->uid,
            'money' => $order->money,
            'refund_money' => $saveAmount,
            'pay_merchant_source' => $order->pay_merchant_source,
            'pay_merchant_id' => $order->pay_merchant_id,
            'trade_no' => $order->trade_no,
            'refund_no' => $refund_no,
            'transaction_id' => $order->transaction_id,
            //'status' => '',
            //'refund_id' => '',
            //'refund_source_msg' => '',
        ];

        if(!$remark) {
            $remark = '任务退款';
        }


        if($payMerchant->source == 'OFFICIALPAY') {
            //微信官方退款
            $wechatPay = WechatPay::instance($payMerchant->source, $payConfig);
            if(!$wechatPay) {
                $resultData['result'] = false;
                $resultData['msg'] = "企业支付通道错误";
            }

            $refundData = [
                'refund_desc'=>$remark,
            ];
            $isPayOk = false;

            if(in_array($order->uid, explode(',',env('TEST_PAY_UID')))){
                //测试的账号，充值都是1分
                $order->money = 1;
            }
            $refundResultInfo = $wechatPay->byOutTradeNumber($order->trade_no, $refund_no, $order->money * 100, $refundMoney, $refundData);
            if($refundResultInfo
                && isset($refundResultInfo['return_code'])
                && $refundResultInfo['return_code'] == 'SUCCESS'
                && isset($refundResultInfo['result_code'])
                && $refundResultInfo['result_code'] == 'SUCCESS') {

                //退款成功
                $orderRefundData['status'] = 'REFUND';
                $orderRefundData['refund_id'] = $refundResultInfo['refund_id'];
                $orderRefundData['refund_source_msg'] = json_encode($refundResultInfo);

                OrderRefundService::saveOrderRefund($orderRefundData);
                //用户任务退款流水
                UserBillService::addRefundBill($order->uid, $saveAmount, $order->task_id, $orderId);

                $isPayOk = true;
            }
            Log::info('微信退款--Official---enter--end------------' . json_encode($refundResultInfo));
            if($isPayOk) {
                $resultData['result'] = true;
                $resultData['msg'] = "退款成功";
            } else {
                $msg = '';
                if($refundResultInfo && isset($refundResultInfo['return_msg'])) {
                    $msg = $refundResultInfo['return_msg'];
                }
                if($refundResultInfo && isset($refundResultInfo['err_code_des']) && $refundResultInfo['err_code_des']) {
                    $msg = $refundResultInfo['err_code_des'];
                }
                $resultData['result'] = false;
                $resultData['msg'] = $msg;
            }
        }

        return $resultData;
    }
















    /**
     * 提现
     * @param $uid String 用户ID
     * @param int $amount 付款金额 单位 分
     * @param string $withdrawCashId 提现ID
     * @param string $remark
     * @return array ['result' => false, 'msg' => ""]
     */
    public static function companyPayToPersonWithdrawCash($uid, $amount, $withdrawCashId = '', $remark = '') {
        return self::companyPayToPerson($uid, $amount, '', $withdrawCashId, '', $remark);
    }

    /**
     *
     * @param $uid String 用户ID
     * @param $amount int 付款金额 单位 分
     * @param string $type  [Refund] 退款，
     * @param string $withdrawCashId 提现ID
     * @param string $taskId 任务ID
     * @param string $remark 备注
     * @return array ['result' => false, 'msg' => ""]
     */
    public static function companyPayToPerson($uid, $amount, $type = '', $withdrawCashId = '', $taskId = '', $remark = '') {
        $resultData = [
            'result' => false,
            'msg' => "",
        ];
        if($amount < 100 || $amount > 20000 * 100) {
            $resultData['msg'] = "付款金额超出限制。低于最小金额1.00元或累计超过20000.00元。";
            return $resultData;
        }

        $isPayWithdraw = false;

        $user = User::getUserInfo($uid);

        $trade_no = date("YmdHis").hexdec(uniqid());

        $payMerchant = PayMerchantService::getCompanyPayPersonPayMerchantSource();
        if(!$payMerchant) {
            $resultData['result'] = false;
            $resultData['msg'] = "企业支付通道不存在";
            return $resultData;
        }
        //微信企业付款
        $payConfig = [];
        if($payMerchant->config_info){
            $publicPath = public_path();
            $payConfig = json_decode($payMerchant->config_info,true);
            $payConfig['cert_path'] = $publicPath.'/' .$payConfig['cert_path'];
            $payConfig['key_path'] = $publicPath.'/' .$payConfig['key_path'];
        }
        $wechatPay = WechatPay::instance($payMerchant->source, $payConfig);
        if(!$wechatPay) {
            $resultData['result'] = false;
            $resultData['msg'] = "企业支付通道错误";
        }

        $saveAmount = $amount / 100;

        $paymentData = [
            'amount' => $saveAmount,
            'amount_person' => 0,
            'remark' => $remark,
            //'pay_time' => '',
            'trade_no' => $trade_no,
            'status' => PayWithdrawCashService::getWithdrawCashStatusStr(20),
            'pay_person_info' => '',
            'pay_merchant_source' => 'wechat',
        ];
        if($withdrawCashId) {
            $paymentData['pay_withdraw_cash_id'] = $withdrawCashId;
            $payWithdrawCash = PayWithdrawCashService::getWithdrawCash($withdrawCashId);
            if($payWithdrawCash) {
                $isPayWithdraw = true;
            }
        }


        $desc = "帮找佣金";
        if($type == "Refund") {
            $desc = "任务退款";
        }
        $payData = [
            'trade_no' => $trade_no,
            'openid'=> $user->openid,
            'person_name' => '',
            'amount'=> $amount,
            'desc'=> $desc,
        ];
        //保存打款信息
        $payPayment = PayPaymentService::addPayPayment($paymentData);
        $payResultInfo = $wechatPay->payToPerson($payData);
        if(!$payResultInfo || count($payResultInfo) == 0){
            $payResultInfo = $wechatPay->payToPerson($payData);
        }
        $isPayOk = false;

        if($payResultInfo
            && isset($payResultInfo['return_code'])
            && $payResultInfo['return_code'] == 'SUCCESS'
            && isset($payResultInfo['result_code'])
            && $payResultInfo['result_code'] == 'SUCCESS') {

            //打款成功
            $payPayment['status'] = PayWithdrawCashService::getWithdrawCashStatusStr(31);
            $payWithdrawCash['status'] = PayWithdrawCashService::getWithdrawCashStatusStr(31);


            //更新用户提现流水
            if($type && $type == "Refund") {
                //用户任务退款
                UserBillService::addRefundBill($uid, $saveAmount, $taskId, "");
            } else {
                //用户提现
                UserBillService::addWithdrawBill($payWithdrawCash->uid, $saveAmount, $payWithdrawCash->id);
            }

            $isPayOk = true;
        } else {
            //打款失败
            $payPayment['status'] = PayWithdrawCashService::getWithdrawCashStatusStr(41);
            $payWithdrawCash['status'] = PayWithdrawCashService::getWithdrawCashStatusStr(41);

        }
        $payResultInfo['pay_merchant_source_msg'] = '';
        if($payResultInfo && isset($payResultInfo['return_msg'])) {
            $payResultInfo['pay_merchant_source_msg'] = $payResultInfo['return_msg'];
        }
        if($payResultInfo && isset($payResultInfo['err_code_des']) && $payResultInfo['err_code_des']) {
            $payResultInfo['pay_merchant_source_msg'] = $payResultInfo['err_code_des'];
        }
        $payPayment['pay_merchant_source_result'] = json_encode($payResultInfo);

        $payPayment->save();

        if($payWithdrawCash && $isPayWithdraw) {
            $payWithdrawCash->save();
        }

        if($isPayOk) {
            $resultData['result'] = true;
            $resultData['msg'] = "企业付款成功";
        } else {
            $msg = $payResultInfo['pay_merchant_source_msg'];
            if(!$msg) {
                $msg = $payResultInfo['return_msg'];
            }
            $resultData['result'] = false;
            $resultData['msg'] = $msg;


        }
        return $resultData;
    }
}